package com.ojoin.trade.common.utils;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ojoin.trade.common.Constants;
import com.ojoin.trade.common.exception.BusinessException;
import com.ojoin.trade.common.utils.file.MimeTypes;

public class DownloadUtils {
	private static Logger log = LoggerFactory.getLogger(DownloadUtils.class);

	/**
	 * 
	 * @param request
	 *            type='preview' 预览,type=null 下载
	 * @param response
	 * @param filePath
	 *            下载源路径
	 * @throws IOException
	 */
	public static void download(HttpServletRequest request,
			HttpServletResponse response, String filePath) throws IOException {
		download(request, response, filePath, "");
	}

	/**
	 * 
	 * @param request
	 *            type='preview' 预览,type=null 下载
	 * @param response
	 * @param filePath
	 *            下载源路径
	 * @param displayName
	 *            下载显示名称
	 * @throws IOException
	 */
	public static void download(HttpServletRequest request,
			HttpServletResponse response, String filePath, String displayName)
			throws IOException {

		filePath = filePath == null ? "" : filePath;
		File file = new File(filePath);

		if (StringUtils.isEmpty(displayName)) {
			displayName = file.getName();
		}

		boolean isIE =CommonUtils.isIE(request);

		String contentType = MimeTypes.guessContentTypeFromName(displayName);

		String type = request.getParameter("type");
		if (null != type && "preview".endsWith(type)) {

			if (!file.exists() || !file.canRead()) {
				response.setContentType("text/html;charset=utf-8");
				response.getWriter().write("您预览的文件不存在！");
				return;
			}

			response.reset();
			response.setContentType(contentType != null ? contentType
					: "text/html;charset=utf-8");
			response.setContentLength((int) file.length());

			String displayFilename = displayName.substring(displayName
					.lastIndexOf("_") + 1);
			displayFilename = displayFilename.replace(" ", "_");
			if (isIE) {
				displayFilename = URLEncoder.encode(displayFilename,
						Constants.ENCODING);
				response.setHeader("Content-Disposition", "inline;filename=\""
						+ displayFilename + "\"");
			} else {
				displayFilename = new String(
						displayFilename.getBytes(Constants.ENCODING),
						"ISO8859-1");
				response.setHeader("Content-Disposition", "inline;filename="
						+ displayFilename);
			}

		} else {

			if (!file.exists() || !file.canRead()) {
				response.setContentType("text/html;charset=utf-8");
				response.getWriter().write("您下载的文件不存在！");
				return;
			}

			response.reset();
			response.setDateHeader("Expires", 0L);

			response.setContentType("application/x-download");
			response.setContentLength((int) file.length());

			String displayFilename = displayName.substring(displayName
					.lastIndexOf("_") + 1);
			displayFilename = displayFilename.replace(" ", "_");
			if (isIE) {
				displayFilename = URLEncoder.encode(displayFilename,
						Constants.ENCODING);
				response.setHeader("Content-Disposition",
						"attachment;filename=\"" + displayFilename + "\"");
			} else {
				//over https @ http://support.microsoft.com/kb/316431
				response.setHeader("Pragma", "No-cache");
				response.setHeader("Cache-Control", "must-revalidate, no-transform");

				displayFilename = new String(
						displayFilename.getBytes(Constants.ENCODING),
						"ISO8859-1");
				response.setHeader("Content-Disposition",
						"attachment;filename=" + displayFilename);
			}

		}
		BufferedInputStream is = null;
		OutputStream os = null;
		try {

			os = response.getOutputStream();
			is = new BufferedInputStream(new FileInputStream(file));
			IOUtils.copy(is, os);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(is);
		}
	}

	/**
	 * 
	 * @param request
	 *            type='preview' 预览,type=null 下载
	 * @param response
	 * @param displayName
	 *            下载显示名称
	 * @param bytes
	 *            下载字节码
	 * @throws IOException
	 */
	public static void download(HttpServletRequest request,
			HttpServletResponse response, String displayName, byte[] bytes)
			throws IOException {

		if (ArrayUtils.isEmpty(bytes)) {
			response.setContentType("text/html;charset=utf-8");
			response.setCharacterEncoding(Constants.ENCODING);
			response.getWriter().write("您下载的文件不存在！");
			return;
		}

		boolean isIE =CommonUtils.isIE(request);

		response.reset();
		response.setDateHeader("Expires", 0L);

		response.setContentType("application/x-download");
		response.setContentLength((int) bytes.length);

		String displayFilename = displayName.substring(displayName
				.lastIndexOf("_") + 1);
		displayFilename = displayFilename.replace(" ", "_");
		if (isIE) {
			displayFilename = URLEncoder.encode(displayFilename,
					Constants.ENCODING);
			response.setHeader("Content-Disposition", "attachment;filename=\""
					+ displayFilename + "\"");
		} else {
			//over https @ http://support.microsoft.com/kb/316431
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "must-revalidate, no-transform");

			displayFilename = new String(
					displayFilename.getBytes(Constants.ENCODING), "ISO8859-1");
			response.setHeader("Content-Disposition", "attachment;filename="
					+ displayFilename);
		}
		BufferedInputStream is = null;
		OutputStream os = null;
		try {

			os = response.getOutputStream();
			is = new BufferedInputStream(new ByteArrayInputStream(bytes));
			IOUtils.copy(is, os);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(is);
		}
	}

	public static File[] getFiles(File file, String s) {

		Pattern p = Pattern.compile(s);

		ArrayList<File> list = filePattern(file, p);
		File[] rtn = null;
		if(!CommonUtils.isEmpty(list)){
			rtn = new File[list.size()];
			list.toArray(rtn);
		}
		
		return rtn;
	}

	public static File[] getFiles(String dir, String s) {
		// 开始的文件夹
		File file = new File(dir);
		return getFiles(file, s);
	}

	public static ArrayList<File> filePattern(File file, Pattern p) {
		if (null == file) {
			return null;
		} else if (file.isFile()) {
			Matcher fMatcher = p.matcher(file.getName());
			if (fMatcher.matches()) {
				ArrayList<File> list = new ArrayList<File>();
				list.add(file);
				return list;
			}
		} else if (file.isDirectory()) {
			File[] files = file.listFiles();
			if (files != null && files.length > 0) {
				ArrayList<File> list = new ArrayList<File>();
				for (int i = 0; i < files.length; i++) {
					ArrayList<File> rlist = filePattern(files[i], p);
					if (rlist != null) {
						list.addAll(rlist);
					}
				}
				return list;
			}
		}
		return null;
	}

	/**
	 * 
	 * 等待文件下载完成，知道文件名
	 * 
	 * @param dir
	 * @param fileNamePrefix
	 * @return
	 * @throws Exception
	 */

	public static File waitFileDownloadOver(File dir,
			final String fileNamePrefix) {
		int count = 10;

		while (count > 0) {
			count--;
			File[] getFiles = getFiles(dir, fileNamePrefix);

			LogUtils.info(log, "文件[" + fileNamePrefix + "]下载等待时间：-->"
					+ (20 - count) * 5);
			
			if (null != getFiles && getFiles.length > 0 && null != getFiles[0]
					&& getFiles[0].canRead()) {
				return getFiles[0];
			}
			WaitUtil.waitTimeSeconds(5);
		}

		return null;

	}


	/**
	 *
	 * 等待文件下载完成,通过监控临时文件
	 *
	 * @param dir
	 * @param fileNamePrefix
	 * @return
	 * @throws Exception
	 */

	public static boolean waitFileDownloadOverByTmp(File dir,
											final String fileNamePrefix) throws Exception {
		int count = 20;

		while (count > 0) {
			count--;
			File[] getFiles = getFiles(dir, fileNamePrefix);

			LogUtils.info(log, "文件[" + fileNamePrefix + "]下载等待时间：-->"
					+ (20 - count) * 5);
			WaitUtil.waitTimeSeconds(5);


			if (null == getFiles ) {
				return true;
			}

		}

		throw new BusinessException("文件下载失败");

	}
}
